package net.tomblog.app.swingheil.parser;

import java.util.ArrayList;
import java.util.List;

import net.tomblog.app.swingheil.activity.BaseActivity;
import net.tomblog.app.swingheil.model.Article;
import net.tomblog.app.swingheil.model.ArticleSearch;
import net.tomblog.app.swingheil.parser.ArticleParser.ArticleListener;
import net.tomblog.app.swingheil.provider.ArticleProvider;
import net.tomblog.app.swingheil.util.L;
import net.tomblog.app.swingheil.util.ParsingException;
import android.app.Activity;
import android.content.ContentValues;
import android.net.Uri;
import android.os.AsyncTask;

/**
 * 네이버 까페에서 글 목록을 가져온다.
 * 
 * @author hyunung.park (parkbear01@gmail.com)
 * 
 */
public class GetArticleListTask extends AsyncTask<ArticleSearch, Integer, Boolean> {

	private static final String TAG = "GetNaverArticleListTask";

	private ArticleParser mArticleParser;
	private ArticleListener mArticleListener;
	private Activity mActivity;
	
	private boolean mNeedProgressDialog;
	private boolean mIsParsingError;
	private boolean mIncreasingSearchPage;
	private int mParsingErrorCount = 1;

	public GetArticleListTask(ArticleParser articleParser,
			ArticleListener articleListener, Activity activity,
			boolean needProgressDialog) {
		mArticleParser = articleParser;
		mArticleListener = articleListener;
		mActivity = activity;
		mNeedProgressDialog = needProgressDialog;
	}

	@Override
	protected void onPreExecute() {
		super.onPreExecute();
		if(mNeedProgressDialog) {
			mActivity.showDialog(BaseActivity.DIALOG_LOADING);
		}
	}
	
	@Override
	protected Boolean doInBackground(ArticleSearch... params) {
		L.d(TAG, " >>> called doInBackground()");

		boolean isInserted = false;
		int articleId = Integer.MAX_VALUE;
		ArticleSearch articleSearch = params[0];
		String cafeId = articleSearch.getCafeId();
		String boardId = articleSearch.getBoardId();
		int searchPage = articleSearch.getSearchPage();
		int searchPerPage = articleSearch.getSearchPerPage();
		mIncreasingSearchPage = articleSearch.isIncreasingSearchPage();

		List<Article> articleList = getArticleList(cafeId, boardId, searchPage, searchPerPage);
		
		for (Article article : articleList) {
			ContentValues values = ArticleProvider.getContentValuesFromArticle(article);
			Uri uri = mActivity.getContentResolver().insert(Article.CONTENT_URI, values);
			
			int newArticleId = Integer.valueOf(uri.getLastPathSegment());
			String baseUri = uri.toString();
			uri = Uri.parse(baseUri.substring(0, baseUri.lastIndexOf("/")));
			
			String lastPath = uri.getLastPathSegment();
			if(lastPath.equals(ArticleProvider.INSERTED)) {
				isInserted = true;
			}

			if(newArticleId < articleId) {
				articleId = newArticleId;
			}
		}
		
		// 첫페이지이고 삽입하는 데이터가 있다면 이전에 있던 데이터는 최근의 데이터가 아닐 가능성이 있기에 삭제한다.
		if(searchPage == 1 && isInserted == true) {
			String[] selectionArgs = new String[] { cafeId, boardId, String.valueOf(articleId)};
			String selection = Article.SELECTION + " AND " + Article.ARTICLE_ID + " < ?";
			mActivity.getContentResolver().delete(Article.CONTENT_URI, selection, selectionArgs);
		}

		boolean isLastPage = (searchPerPage > articleList.size()) ?  true : false;

		return isLastPage;
	} 
	
	@Override
	protected void onPostExecute(Boolean isLastPage) {
		L.e(TAG, " >>> called onPostExecute()");
		
		if(mIsParsingError) {
			mArticleListener.onError(ArticleListener.ERROR_NETWORK_PROBLEM, "network problem");
		}else {
			boolean needToIncreasePaging = false;
			if(mIncreasingSearchPage) {
				needToIncreasePaging = (isLastPage == true) ? false : true;
			}
			mArticleListener.onComplete(needToIncreasePaging);
		}
		
		if(mNeedProgressDialog) {
			mActivity.removeDialog(BaseActivity.DIALOG_LOADING);
		}
	}

	@Override
	protected void onCancelled() {
		L.e(TAG, " >>> called onCancelled()");
		mArticleParser.cancelGettingArticleList();
		mArticleListener.onError(ArticleListener.ERROR_CANCELED, "getting article list was canceled");
	}
	
	private List<Article> getArticleList(String cafeId, String boardId, int searchPage, int searchPerPage) {
		L.e(TAG, " >>> called getArticleList() cafeId : " + cafeId + " boardId : " + boardId + " searchPage : " + searchPage + " searchPerPage : " + searchPerPage);
		
		List<Article> articleList = null;
		try {
			articleList = mArticleParser.getArticleList(cafeId, boardId, searchPage, searchPerPage);
		} catch (ParsingException e) {
			L.e(TAG, " >>> called ParsingException() : " + e.getMessage() + " parsingErrorCount : " + mParsingErrorCount);
			if(mParsingErrorCount < 5) {
				articleList = getArticleList(cafeId, boardId, searchPage, searchPerPage);
			}else {
				articleList = new ArrayList<Article>();
			}
			mParsingErrorCount++;
		} catch (Exception e) {
			mIsParsingError = true;
			articleList = new ArrayList<Article>();
		}
		
		return articleList;
	}
}
